/**
 * SVG原型图优化处理器
 * 根据设计规范对SVG文件进行标准化和优化
 */

const fs = require('fs');
const path = require('path');
const { JSDOM } = require('jsdom');

class SVGOptimizer {
  constructor(designStandards) {
    this.standards = designStandards;
    this.dom = new JSDOM();
    this.document = this.dom.window.document;
  }

  /**
   * 优化单个SVG文件
   * @param {string} svgContent - SVG文件内容
   * @param {string} fileName - 文件名
   * @returns {Object} 优化结果
   */
  optimizeSVG(svgContent, fileName) {
    try {
      // 解析SVG
      const parser = new this.dom.window.DOMParser();
      const svgDoc = parser.parseFromString(svgContent, 'image/svg+xml');
      const svgElement = svgDoc.documentElement;

      if (!svgElement || svgElement.tagName !== 'svg') {
        throw new Error('Invalid SVG format');
      }

      const changes = [];
      
      // 1. 标准化画布尺寸
      this.standardizeCanvas(svgElement, changes);
      
      // 2. 优化色彩系统
      this.optimizeColors(svgElement, changes);
      
      // 3. 优化文本渲染
      this.optimizeText(svgElement, changes);
      
      // 4. 优化布局和间距
      this.optimizeLayout(svgElement, changes);
      
      // 5. 优化效果和滤镜
      this.optimizeEffects(svgElement, changes);
      
      // 6. 清理和压缩
      this.cleanupSVG(svgElement, changes);

      // 序列化结果
      const serializer = new this.dom.window.XMLSerializer();
      const optimizedContent = serializer.serializeToString(svgDoc);

      return {
        success: true,
        originalFile: fileName,
        optimizedContent: this.formatSVG(optimizedContent),
        changes: changes,
        metrics: this.calculateMetrics(svgContent, optimizedContent)
      };
    } catch (error) {
      return {
        success: false,
        originalFile: fileName,
        error: error.message,
        changes: []
      };
    }
  }

  /**
   * 标准化画布尺寸
   */
  standardizeCanvas(svgElement, changes) {
    const canvas = this.standards.canvas;
    
    // 设置标准尺寸
    if (svgElement.getAttribute('width') !== canvas.width.toString()) {
      svgElement.setAttribute('width', canvas.width);
      changes.push(`Canvas width standardized to ${canvas.width}`);
    }
    
    if (svgElement.getAttribute('height') !== canvas.height.toString()) {
      svgElement.setAttribute('height', canvas.height);
      changes.push(`Canvas height standardized to ${canvas.height}`);
    }
    
    if (svgElement.getAttribute('viewBox') !== canvas.viewBox) {
      svgElement.setAttribute('viewBox', canvas.viewBox);
      changes.push(`ViewBox standardized to ${canvas.viewBox}`);
    }
  }

  /**
   * 优化色彩系统
   */
  optimizeColors(svgElement, changes) {
    const colorMap = this.createColorMap();
    const elements = svgElement.querySelectorAll('*');
    
    elements.forEach(element => {
      // 优化fill属性
      const fill = element.getAttribute('fill');
      if (fill && colorMap[fill]) {
        element.setAttribute('fill', colorMap[fill]);
        changes.push(`Color ${fill} mapped to ${colorMap[fill]}`);
      }
      
      // 优化stroke属性
      const stroke = element.getAttribute('stroke');
      if (stroke && colorMap[stroke]) {
        element.setAttribute('stroke', colorMap[stroke]);
        changes.push(`Stroke color ${stroke} mapped to ${colorMap[stroke]}`);
      }
      
      // 优化style属性中的颜色
      const style = element.getAttribute('style');
      if (style) {
        let newStyle = style;
        Object.keys(colorMap).forEach(oldColor => {
          const regex = new RegExp(oldColor.replace('#', '\\#'), 'gi');
          if (regex.test(newStyle)) {
            newStyle = newStyle.replace(regex, colorMap[oldColor]);
            changes.push(`Style color ${oldColor} mapped to ${colorMap[oldColor]}`);
          }
        });
        if (newStyle !== style) {
          element.setAttribute('style', newStyle);
        }
      }
    });
  }

  /**
   * 创建颜色映射表
   */
  createColorMap() {
    const colors = this.standards.colors;
    return {
      // 常见的旧颜色到新颜色的映射
      '#007AFF': colors.primary,
      '#0066CC': colors.primary,
      '#1976D2': colors.primary,
      '#34C759': colors.secondary,
      '#4CAF50': colors.secondary,
      '#00C851': colors.secondary,
      '#F2F2F7': colors.background,
      '#FAFAFA': colors.background,
      '#F5F5F5': colors.background,
      '#FFFFFF': colors.cardBackground,
      '#000000': colors.textPrimary,
      '#333333': colors.textPrimary,
      '#666666': colors.textSecondary,
      '#999999': colors.textLight,
      '#CCCCCC': colors.border,
      '#E0E0E0': colors.border,
      '#EEEEEE': colors.border
    };
  }

  /**
   * 优化文本渲染
   */
  optimizeText(svgElement, changes) {
    const typography = this.standards.typography;
    const textElements = svgElement.querySelectorAll('text, tspan');
    
    textElements.forEach(element => {
      // 设置字体族
      if (!element.getAttribute('font-family')) {
        element.setAttribute('font-family', typography.fontFamily);
        changes.push('Font family standardized');
      }
      
      // 优化文本锚点
      if (!element.getAttribute('text-anchor')) {
        element.setAttribute('text-anchor', typography.textAnchor);
        changes.push('Text anchor standardized');
      }
      
      // 优化基线对齐
      if (!element.getAttribute('dominant-baseline')) {
        element.setAttribute('dominant-baseline', typography.dominantBaseline);
        changes.push('Dominant baseline standardized');
      }
      
      // 标准化字体大小
      const fontSize = element.getAttribute('font-size');
      if (fontSize) {
        const standardSize = this.getStandardFontSize(parseInt(fontSize));
        if (standardSize !== parseInt(fontSize)) {
          element.setAttribute('font-size', standardSize);
          changes.push(`Font size ${fontSize} standardized to ${standardSize}`);
        }
      }
    });
  }

  /**
   * 获取标准字体大小
   */
  getStandardFontSize(size) {
    const sizes = this.standards.typography.sizes;
    const sizeValues = Object.values(sizes).sort((a, b) => a - b);
    
    // 找到最接近的标准尺寸
    let closest = sizeValues[0];
    let minDiff = Math.abs(size - closest);
    
    sizeValues.forEach(standardSize => {
      const diff = Math.abs(size - standardSize);
      if (diff < minDiff) {
        minDiff = diff;
        closest = standardSize;
      }
    });
    
    return closest;
  }

  /**
   * 优化布局和间距
   */
  optimizeLayout(svgElement, changes) {
    const layout = this.standards.layout;
    
    // 优化圆角
    const rectElements = svgElement.querySelectorAll('rect');
    rectElements.forEach(rect => {
      const rx = rect.getAttribute('rx');
      if (rx) {
        const standardRadius = this.getStandardBorderRadius(parseInt(rx));
        if (standardRadius !== parseInt(rx)) {
          rect.setAttribute('rx', standardRadius);
          rect.setAttribute('ry', standardRadius);
          changes.push(`Border radius ${rx} standardized to ${standardRadius}`);
        }
      }
    });
  }

  /**
   * 获取标准圆角大小
   */
  getStandardBorderRadius(radius) {
    const radiusValues = Object.values(this.standards.layout.borderRadius);
    const numericValues = radiusValues.filter(v => typeof v === 'number').sort((a, b) => a - b);
    
    let closest = numericValues[0];
    let minDiff = Math.abs(radius - closest);
    
    numericValues.forEach(standardRadius => {
      const diff = Math.abs(radius - standardRadius);
      if (diff < minDiff) {
        minDiff = diff;
        closest = standardRadius;
      }
    });
    
    return closest;
  }

  /**
   * 优化效果和滤镜
   */
  optimizeEffects(svgElement, changes) {
    // 优化阴影效果
    const elementsWithShadow = svgElement.querySelectorAll('[filter], [style*="drop-shadow"], [style*="box-shadow"]');
    
    elementsWithShadow.forEach(element => {
      const style = element.getAttribute('style');
      if (style && (style.includes('drop-shadow') || style.includes('box-shadow'))) {
        // 将CSS阴影转换为SVG滤镜
        const filterId = this.createShadowFilter(svgElement);
        element.setAttribute('filter', `url(#${filterId})`);
        
        // 清理原有的阴影样式
        const newStyle = style.replace(/drop-shadow\([^)]*\)/g, '')
                              .replace(/box-shadow\s*:[^;]*/g, '')
                              .replace(/;\s*;/g, ';')
                              .trim();
        
        if (newStyle) {
          element.setAttribute('style', newStyle);
        } else {
          element.removeAttribute('style');
        }
        
        changes.push('Shadow effect optimized to SVG filter');
      }
    });
  }

  /**
   * 创建标准阴影滤镜
   */
  createShadowFilter(svgElement) {
    const filterId = 'standardShadow';
    
    // 检查是否已存在
    if (svgElement.querySelector(`#${filterId}`)) {
      return filterId;
    }
    
    // 创建defs元素（如果不存在）
    let defs = svgElement.querySelector('defs');
    if (!defs) {
      defs = this.document.createElementNS('http://www.w3.org/2000/svg', 'defs');
      svgElement.insertBefore(defs, svgElement.firstChild);
    }
    
    // 创建滤镜
    const filter = this.document.createElementNS('http://www.w3.org/2000/svg', 'filter');
    filter.setAttribute('id', filterId);
    filter.setAttribute('x', '-20%');
    filter.setAttribute('y', '-20%');
    filter.setAttribute('width', '140%');
    filter.setAttribute('height', '140%');
    
    // 创建阴影效果
    const feDropShadow = this.document.createElementNS('http://www.w3.org/2000/svg', 'feDropShadow');
    feDropShadow.setAttribute('dx', '0');
    feDropShadow.setAttribute('dy', '2');
    feDropShadow.setAttribute('stdDeviation', '4');
    feDropShadow.setAttribute('flood-color', 'rgba(0, 0, 0, 0.1)');
    
    filter.appendChild(feDropShadow);
    defs.appendChild(filter);
    
    return filterId;
  }

  /**
   * 清理和压缩SVG
   */
  cleanupSVG(svgElement, changes) {
    // 移除空的属性
    const allElements = svgElement.querySelectorAll('*');
    allElements.forEach(element => {
      Array.from(element.attributes).forEach(attr => {
        if (!attr.value || attr.value.trim() === '') {
          element.removeAttribute(attr.name);
          changes.push(`Removed empty attribute: ${attr.name}`);
        }
      });
    });
    
    // 移除不必要的命名空间
    const unnecessaryNamespaces = ['xmlns:xlink'];
    unnecessaryNamespaces.forEach(ns => {
      if (svgElement.hasAttribute(ns)) {
        svgElement.removeAttribute(ns);
        changes.push(`Removed unnecessary namespace: ${ns}`);
      }
    });
  }

  /**
   * 格式化SVG输出
   */
  formatSVG(svgContent) {
    // 基本的格式化
    return svgContent
      .replace(/></g, '>\n<')
      .replace(/^\s+|\s+$/gm, '')
      .split('\n')
      .map(line => {
        const depth = (line.match(/</g) || []).length - (line.match(/\//g) || []).length;
        return '  '.repeat(Math.max(0, depth - 1)) + line;
      })
      .join('\n');
  }

  /**
   * 计算优化指标
   */
  calculateMetrics(originalContent, optimizedContent) {
    const originalSize = Buffer.byteLength(originalContent, 'utf8');
    const optimizedSize = Buffer.byteLength(optimizedContent, 'utf8');
    const compressionRatio = ((originalSize - optimizedSize) / originalSize * 100).toFixed(2);
    
    return {
      originalSize,
      optimizedSize,
      compressionRatio: `${compressionRatio}%`,
      sizeReduction: originalSize - optimizedSize
    };
  }

  /**
   * 批量处理文件
   */
  async processBatch(inputDir, outputDir, progressCallback) {
    const files = fs.readdirSync(inputDir).filter(file => file.endsWith('.svg'));
    const results = [];
    
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const inputPath = path.join(inputDir, file);
      const outputPath = path.join(outputDir, file);
      
      try {
        const svgContent = fs.readFileSync(inputPath, 'utf8');
        const result = this.optimizeSVG(svgContent, file);
        
        if (result.success) {
          // 确保输出目录存在
          if (!fs.existsSync(outputDir)) {
            fs.mkdirSync(outputDir, { recursive: true });
          }
          
          fs.writeFileSync(outputPath, result.optimizedContent, 'utf8');
          result.outputPath = outputPath;
        }
        
        results.push(result);
        
        if (progressCallback) {
          progressCallback(i + 1, files.length, file, result.success);
        }
      } catch (error) {
        results.push({
          success: false,
          originalFile: file,
          error: error.message
        });
      }
    }
    
    return results;
  }
}

module.exports = SVGOptimizer;